package dm.bsi;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import org.dom4j.DocumentException;

import indi.zjh.dp.db.Session;
import indi.zjh.dp.error.CommandExecuteException;
import indi.zjh.dp.error.UnsuportedFieldException;
import indi.zjh.dp.orm.Query;
import indi.zjh.dp.orm.Relation;
import indi.zjh.dp.orm.Result;
import indi.zjh.dp.type.String128;
import indi.zjh.dp.util.SystemCmd;

public class Node extends LogNode{
	protected String name = "nil";
	protected String ip = "nil";
	protected String dockerGatewayIp = "nil";
	protected String128 osInfo = new String128("nil");
	protected int cpuUsedRate = 0;
	protected int memUsedRate = 0;
	protected String128 memInfo = new String128("nil");
	protected boolean isReady = false;
	protected long cpuUsedTime = 0;
	protected long cpuIdleTime = 0;
	
	protected Relation containers = new Relation(Container.class);
	protected Relation images = new Relation(Image.class);
	protected Relation backups = new Relation(Backup.class);
	
	/**
	 * 检测nginx容器是否正常运行
	 * @return
	 * @throws CommandExecuteException 
	 */
	public boolean isNginxRunning() throws CommandExecuteException
	{
		if(this.ip.equals("nil"))
			return false;
		String cmd = "ssh root@"+this.ip+" docker ps -a --format='{{.Names}}#{{.Status}}' | grep dmnginxContainer";
		String response = SystemCmd.execCMD(cmd, 5).toLowerCase().trim();
		if(response.contains("#up"))
			return true;
		return false;
	}
	
	/**
	 * 下载镜像
	 * @param image
	 * @throws Exception 
	 * @throws DocumentException 
	 * @throws UnsuportedFieldException 
	 */
	public void downloadImage(Session session, Image image) throws UnsuportedFieldException, DocumentException, Exception
	{
		if(this.getIp().equals("nil"))
			return;
		if(!this.isReady)
			return;
		
		String cmd = "ssh root@"+this.getIp()+" docker pull "+image.getName();
		String response = SystemCmd.execCMD(cmd, 300).trim();
		//System.out.println("downloadImage response = "+response);
		this.getImages().add(image);
		image.getNodes().add(this);
		session.save(this).save(image);
	}
	
	/**
	 * 获取状态正常的Node列表
	 * @param session
	 * @return
	 * @throws Exception 
	 * @throws UnsuportedFieldException 
	 * @throws DocumentException 
	 * @throws SQLException 
	 */
	public static Node[] listReadyNodes(Session session) throws SQLException, DocumentException, UnsuportedFieldException, Exception
	{
		Query<Node> query = new Query<Node>(session);
		Result<Node> result = query.find(Node.class).result();
		Iterator<Node> iter = result.iterator();
		//Node[] nodes = new Node[result.count()];
		ArrayList<Node> nodes = new ArrayList<Node>();
		int i = 0;
		while(iter.hasNext())
		{
			Node node = iter.next();
			
			node.debug();
			if(node.isReady)
			{
				nodes.add(node);
			}
		}
		Node[] declare = new Node[nodes.size()];
		return nodes.toArray(declare);
	}
	
	public Relation getContainers() {
		return containers;
	}

	public Relation getImages() {
		return images;
	}
	
	public static String toDictString(Method m)
	{
		if(m.getName().equals("isNginxRunning"))
		{
			return "判断nginx是否正常运行";
		}
		else if(m.getName().equals("downloadImage"))
		{
			return "下载指定镜像";
		}
		else if(m.getName().equals("listReadyNodes"))
		{
			return "列出准备就绪的节点";
		}

		return LogNode.toDictString(m);
	}

	public static String toDictString(Field f)
	{
		if(f.getName().equals("name"))
		{
			return "服务器节点名称, 用来显示和标识服务器";
		}
		else if(f.getName().equals("ip"))
		{
			return "服务器节点IP地址, 用来服务器节点的通信与管理";
		}
		else if(f.getName().equals("osInfo"))
		{
			return "服务器节点操作系统信息";
		}
		else if(f.getName().equals("cpuUsedRate"))
		{
			return "服务器CPU使用率, 范围0-100, 百分比";
		}
		else if(f.getName().equals("memUsedRate"))
		{
			return "服务器内存使用率, 范围0-100, 百分比";
		}
		else if(f.getName().equals("memInfo"))
		{
			return "服务器内存信息";
		}
		else if(f.getName().equals("isReady"))
		{
			return "服务器节点是否准备就绪, 就绪后方可在上面运行容器";
		}
		else if(f.getName().equals("cpuUsedTime"))
		{
			return "服务器节点CPU使用时间片";
		}
		else if(f.getName().equals("cpuIdleTime"))
		{
			return "服务器节点CPU空闲时间片";
		}
		else if(f.getName().equals("dockerGatewayIp"))
		{
			return "服务器节点docker网关地址";
		}
		else if(f.getName().equals("containers"))
		{
			return "节点上运行的容器";
		}
		else if(f.getName().equals("images"))
		{
			return "节点上关联的镜像";
		}
		else if(f.getName().equals("backups"))
		{
			return "节点上的备份";
		}

		return LogNode.toDictString(f);
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	

	public String getDockerGatewayIp() {
		return dockerGatewayIp;
	}

	public void setDockerGatewayIp(String dockerGatewayIp) {
		this.dockerGatewayIp = dockerGatewayIp;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getOsInfo() {
		return osInfo.string;
	}

	public void setOsInfo(String osInfo) {
		this.osInfo.string = osInfo;
	}

	public int getCpuUsedRate() {
		return cpuUsedRate;
	}

	public void setCpuUsedRate(int cpuUsedRate) {
		this.cpuUsedRate = cpuUsedRate;
	}

	public int getMemUsedRate() {
		return memUsedRate;
	}

	public void setMemUsedRate(int memUsedRate) {
		this.memUsedRate = memUsedRate;
	}

	public String getMemInfo() {
		return memInfo.string;
	}

	public void setMemInfo(String memInfo) {
		this.memInfo.string = memInfo;
	}
	
	

	public boolean isReady() {
		return isReady;
	}

	public void setReady(boolean isReady) {
		this.isReady = isReady;
	}
	
	

	public Relation getBackups() {
		return backups;
	}

	public long getCpuUsedTime() {
		return cpuUsedTime;
	}

	public void setCpuUsedTime(long cpuUsedTime) {
		this.cpuUsedTime = cpuUsedTime;
	}

	public long getCpuIdleTime() {
		return cpuIdleTime;
	}

	public void setCpuIdleTime(long cpuIdleTime) {
		this.cpuIdleTime = cpuIdleTime;
	}

	@Override
	public String toString() {
		return "Node [name=" + name + ", ip=" + ip + ", dockerGatewayIp=" + dockerGatewayIp + ", osInfo=" + osInfo
				+ ", cpuUsedRate=" + cpuUsedRate + ", memUsedRate=" + memUsedRate + ", memInfo=" + memInfo
				+ ", isReady=" + isReady + ", cpuUsedTime=" + cpuUsedTime + ", cpuIdleTime=" + cpuIdleTime
				+ ", containers=" + containers + ", images=" + images + ", backups=" + backups + ", _id=" + _id
				+ ", _v=" + _v + "]";
	}
	
	
}
